home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / include / asm / bitops.h next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  3.6 KB  |  158 lines

  1. #ifndef _ASM_BITOPS_H
  2. #define _ASM_BITOPS_H
  3. /*
  4.  * Copyright 1992, Linus Torvalds.
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. #ifdef __i386__
  12. /*
  13.  * These have to be done with inline assembly: that way the bit-setting
  14.  * is guaranteed to be atomic. All bitoperations return 0 if the bit
  15.  * was cleared before the operation and != 0 if it was not.
  16.  *
  17.  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  18.  */
  19.  
  20. /*
  21.  * Some hacks to defeat gcc over-optimizations..
  22.  */
  23. struct __dummy { unsigned long a[100]; };
  24. #define ADDR (*(struct __dummy *) addr)
  25.  
  26. extern __inline__ int set_bit(int nr, void * addr)
  27. {
  28.     int oldbit;
  29.  
  30.     __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
  31.         :"=r" (oldbit),"=m" (ADDR)
  32.         :"r" (nr));
  33.     return oldbit;
  34. }
  35.  
  36. extern __inline__ int clear_bit(int nr, void * addr)
  37. {
  38.     int oldbit;
  39.  
  40.     __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
  41.         :"=r" (oldbit),"=m" (ADDR)
  42.         :"r" (nr));
  43.     return oldbit;
  44. }
  45.  
  46. /*
  47.  * This routine doesn't need to be atomic, but it's faster to code it
  48.  * this way.
  49.  */
  50. extern __inline__ int test_bit(int nr, void * addr)
  51. {
  52.     int oldbit;
  53.  
  54.     __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
  55.         :"=r" (oldbit)
  56.         :"m" (ADDR),"r" (nr));
  57.     return oldbit;
  58. }
  59.  
  60. #elif defined(__mc68000__)
  61. /*
  62.  * mc680x0 equivalents.  Require 68020 or better.
  63.  *
  64.  * They don't use the standard m680x0 bit ordering.
  65.  * Instead, the use the standard m680x0 bitfield ordering.
  66.  *
  67.  * Thus, bit 0 is the MSB of addr; bit 32 is the MSB of (addr+1).
  68.  */
  69.  
  70. extern __inline__ int set_bit(int nr,void * vaddr)
  71. {
  72.     char retval;
  73.  
  74.     __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
  75.          : "=d" (retval) : "d" (nr), "a" (vaddr));
  76.  
  77.     return retval;
  78. }
  79.  
  80. extern __inline__ int clear_bit(int nr, void * vaddr)
  81. {
  82.     char retval;
  83.  
  84.     __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
  85.          : "=d" (retval) : "d" (nr), "a" (vaddr));
  86.  
  87.     return retval;
  88. }
  89.  
  90. extern __inline__ int test_bit(int nr, void * vaddr)
  91. {
  92.     char retval;
  93.  
  94.     __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
  95.          : "=d" (retval) : "d" (nr), "a" (vaddr));
  96.  
  97.     return retval;
  98. }
  99. #else
  100. /*
  101.  * For the benefit of those who are trying to port Linux to another
  102.  * architecture, here are some C-language equivalents.    You should
  103.  * recode these in the native assmebly language, if at all possible.
  104.  * To guarantee atomicity, these routines call cli() and sti() to
  105.  * disable interrupts while they operate.  (You have to provide inline
  106.  * routines to cli() and sti().)
  107.  *
  108.  * Also note, these routines assume that you have 32 bit integers.
  109.  * You will have to change this if you are trying to port Linux to the
  110.  * Alpha architecture or to a Cray.  :-)
  111.  *
  112.  * C language equivalents written by Theodore Ts'o, 9/26/92
  113.  */
  114.  
  115. extern __inline__ int set_bit(int nr,void * vaddr)
  116. {
  117.     int          mask, retval;
  118.     unsigned long *addr = (unsigned long *)vaddr;
  119.     unsigned long flags;
  120.     
  121.     addr += nr >> 5;
  122.     mask = 1 << (nr & 0x1f);
  123.     save_flags (flags);
  124.     cli();
  125.     retval = (mask & *addr) != 0;
  126.     *addr |= mask;
  127.     restore_flags(flags);
  128.     return retval;
  129. }
  130.  
  131. extern __inline__ int clear_bit(int nr, void * vaddr)
  132. {
  133.     int    mask, retval;
  134.     unsigned long *addr = (unsigned long *)vaddr;
  135.     unsigned long flags;
  136.  
  137.     addr += nr >> 5;
  138.     mask = 1 << (nr & 0x1f);
  139.     save_flags (flags);
  140.     cli();
  141.     retval = (mask & *addr) != 0;
  142.     *addr &= ~mask;
  143.     restore_flags (flags);
  144.     return retval;
  145. }
  146.  
  147. extern __inline__ int test_bit(int nr, void * vaddr)
  148. {
  149.     int    mask;
  150.     unsigned long *addr = (unsigned long *)vaddr;
  151.  
  152.     addr += nr >> 5;
  153.     mask = 1 << (nr & 0x1f);
  154.     return ((mask & *addr) != 0);
  155. }
  156. #endif    /* i386 */
  157. #endif /* _ASM_BITOPS_H */
  158.